﻿#include <iostream>
#include <Winsock2.h>
#include <Ws2tcpip.h>
#include <string>
#include <map>
#include <thread>
#include <mutex>
#include <chrono>
#include <fstream>
#include <sstream>

#pragma comment(lib, "Ws2_32.lib")

std::map<std::string, int> licenseMap;
std::mutex licenseMutex;
std::string license = "0123456789";
std::map<std::string, std::chrono::system_clock::time_point> status;

int permitnumber = 2;

//检查崩溃的时间
double checktime = 10;

void writeIpToCsv()
{
    std::ofstream outFile("data.csv");
    if (!outFile.is_open()) {
        return;
    }
    outFile << license << "," << licenseMap[license] << std::endl;
    for (const auto& entry : status) {
        outFile << entry.first << ",";
    }
    outFile.close();
}

bool isWhitespace(const std::string& str) {
    for (char c : str) {
        if (!std::isspace(c)) {
            return false;
        }
    }
    return true;
}

void readIp()
{
    std::string fileName = "data.csv";
    std::ifstream inputFile(fileName);

    if (!inputFile.is_open()) {
        //std::cerr << "Error: Unable to open file " << fileName << std::endl;
        return;
    }

    std::string line;
    int n = 0;
    while (std::getline(inputFile, line)) {
        // 使用 std::stringstream 分割每一行数据
        std::stringstream lineStream(line);
        std::string cell;

        // 按逗号分割每个数据
        while (std::getline(lineStream, cell, ',')) {
            // 处理每个数据
            if (!cell.empty() && !isWhitespace(cell))
            {
                if (n == 0) { license = cell; n++; }

                else if (n == 1) {
                    //载入程序上次运行的许可证剩余接入设备数
                    licenseMap[license] = min(std::stoi(cell), permitnumber);

                    n++;
                }
                else {
                    status[cell] = std::chrono::system_clock::now();
                }

            }
        }

    }

    inputFile.close();
}


void handleClient(SOCKET clientSocket) {

    // 接收客户端发来的序列号
    char buffer[1024];
    int bytesReceived = recv(clientSocket, buffer, sizeof(buffer) - 1, 0);
    if (bytesReceived > 0) {
        buffer[bytesReceived] = '\0';

        // 解析消息，提取IP地址和序列号
        std::string message(buffer);
        size_t delimiterPos = message.find('|');
        std::string ipAddress = message.substr(0, delimiterPos);
        std::string licenseKey = message.substr(delimiterPos + 1);

        if (licenseKey == "RUNNING")
        {
            std::cout << "IP address : " << ipAddress << "更新" << std::endl;
            status[ipAddress] = std::chrono::system_clock::now();
        }

        else {
            //isAuthorized 0表示许可证错误，1表示许可证正确（允许接入），2表示许可证正确（人数超限不允许接入）
            int isAuthorized = 0;
            {
                std::lock_guard<std::mutex> lock(licenseMutex);
                auto licenseIter = licenseMap.find(licenseKey);
                if (licenseIter != licenseMap.end()) {
                    isAuthorized = 2;
                    if (licenseIter->second > 0)
                    {
                        isAuthorized = 1;
                        licenseIter->second--;
                    }
                }
            }

            // 向客户端发送授权结果
            if (isAuthorized == 1) {
                send(clientSocket, "AUTHORIZED", 10, 0);
                std::cout << "IP address: " << ipAddress << "接入" << std::endl;
                status[ipAddress] = std::chrono::system_clock::now();
                writeIpToCsv();
            }
            else if (isAuthorized == 0) {
                send(clientSocket, "REJECTED", 8, 0);
            }
            else if (isAuthorized == 2)
            {
                send(clientSocket, "OVERRUN", 7, 0);
            }
        }
    }

    // 关闭客户端套接字
    closesocket(clientSocket);

}


void checkLicense() {
    while (true) {
        for (auto it = status.begin(); it != status.end();) {
            std::string ip = it->first;
            std::chrono::system_clock::time_point timestamp = it->second;

            std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
            std::chrono::duration<double> elapsed = now - timestamp;
            if (elapsed.count() > checktime)
            {
                std::cout << "IP address : " << ip << "断开" << std::endl;
                licenseMap[license] += 1;
                it = status.erase(it); // 使用迭代器删除元素，并更新迭代器
                break; // 跳出循环，避免多次自增

            }
            else {
                ++it; // 仅当不删除元素时才递增迭代器
            }
        }
        std::cout << "当前许可证 " + license + " 剩余接入设备数量：  " << licenseMap[license] << std::endl;
        // 休眠7秒
        std::this_thread::sleep_for(std::chrono::seconds(7));
    }
}

int main() {

    // 创建许可证示例（实际应用中，应从数据库或其他途径获取）
    licenseMap[license] = permitnumber;

    //继承上次程序关闭的许可证软件接入信息
    readIp();

    // 初始化Winsock
    WSADATA wsaData;
    int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (result != 0) {
        std::cerr << "WSAStartup failed: " << result << std::endl;
        return 1;
    }



    // 创建服务器套接字
    SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (serverSocket == INVALID_SOCKET) {
        std::cerr << "Error creating socket: " << WSAGetLastError() << std::endl;
        WSACleanup();
        return 1;
    }

    // 绑定套接字
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = INADDR_ANY;//设置ip
    serverAddr.sin_port = htons(12345);//设置端口
    if (bind(serverSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
        std::cerr << "Error binding socket: " << WSAGetLastError() << std::endl;
        closesocket(serverSocket);
        WSACleanup();
        return 1;
    }

    // 监听套接字
    if (listen(serverSocket, SOMAXCONN) == SOCKET_ERROR) {
        std::cerr << "Error listening on socket: " << WSAGetLastError() << std::endl;
        closesocket(serverSocket);
        WSACleanup();
        return 1;
    }

    std::cout << "License server is running." << std::endl;

    //检查客户端是否崩溃
    std::thread checktimeThread(checkLicense);

    // 无限循环以接受新客户端连接
    while (true) {

        sockaddr_in clientAddr;
        int clientAddrSize = sizeof(clientAddr);

        // 接受客户端连接
        SOCKET clientSocket = accept(serverSocket, (sockaddr*)&clientAddr, &clientAddrSize);
        if (clientSocket == INVALID_SOCKET) {
            std::cerr << "Error accepting client connection: " << WSAGetLastError() << std::endl;
            continue;
        }

        // 创建新线程处理客户端请求
        std::thread clientThread(handleClient, clientSocket);
        clientThread.detach();
    }

    // 关闭服务器套接字
    closesocket(serverSocket);

    // 清理Winsock库
    WSACleanup();

    checktimeThread.join();
    return 0;
}